﻿namespace IS.Projecto.ImportarCSV
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using Modelo;

    public static class CsvParser
    {
        public static Curso GetCurso(string line)
        {
            //ORIGEM;CD_CURSO;CD_ALUNO;CD_DISCIP
            string[] items = line.Split(new[] {';', ','});

            //verifica se o nº de argumento é o correcto
            if (items.Length != 4)
                throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (4).");

            int cursoId = Convert.ToInt32(items[1]);

            return new Curso {Id = cursoId};
        }

        public static IList<Curso> GetAllCursos(Stream stream, bool ignoreFirstLine)
        {
            var reader = new StreamReader(stream);
            var lista = new List<Curso>();

            if (ignoreFirstLine && !reader.EndOfStream)
                reader.ReadLine();

            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                lista.Add(GetCurso(line));
            }
            return lista;
        }

        public static Inscricao GetInscricao(string line)
        {
            //ORIGEM;CD_CURSO;CD_ALUNO;CD_DISCIP
            string[] items = line.Split(new[] {';', ','});

            //verifica se o nº de argumento é o correcto
            if (items.Length != 4)
                throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (4).");

            string origem = items[0];
            int cursoId = Convert.ToInt32(items[1]);
            int alunoId = Convert.ToInt32(items[2]);
            int ucId = Convert.ToInt32(items[3]);

            return new Inscricao {Id = -1, CursoId = cursoId, EstudanteId = alunoId, UcId = ucId, Origem = origem};
        }

        public static IList<Inscricao> GetAllInscricoes(Stream stream, bool ignoreFirstLine)
        {
            var reader = new StreamReader(stream);
            var lista = new List<Inscricao>();

            if (ignoreFirstLine && !reader.EndOfStream)
                reader.ReadLine();

            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine();
                lista.Add(GetInscricao(line));
            }
            return lista;
        }

        public static Horario GetHorario(string line, IList<Docente> docentes)
        {
            //ID_UC;DS_Discip;ID_Turno;Data_Aula;Hora_Inicio;Hora_Fim;ID_Sala;Sala;Docente
            string[] items = line.Split(new[] {';', ','});

            //verifica se o nº de argumento é o correcto
            if (items.Length != 9)
                throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (9).");

            int ucId = Convert.ToInt32(items[0]);
            string disciplina = items[1];
            int turnoId = Convert.ToInt32(items[2]);
            DateTime dataAula = Convert.ToDateTime(items[3]);
            DateTime horaInicio = Convert.ToDateTime(items[4]);
            DateTime horaFim = Convert.ToDateTime(items[5]);
            int salaId = Convert.ToInt32(items[6]);
            //var sala = items[7];
            int a = disciplina.LastIndexOf('(') + 1;
            string tipoAula = disciplina.Substring(a, disciplina.LastIndexOf(')') - a);
            string docenteNome = items[8];
            int docenteId = docentes[docentes.IndexOf(new Docente {Nome = docenteNome})].Id;
            TimeSpan duracaoAula = horaFim.Subtract(horaInicio);

            return new Horario
                       {
                           Id = -1,
                           UcId = ucId,
                           SalaId = salaId,
                           DocenteId = docenteId,
                           TurnoId = turnoId,
                           DataHora = dataAula.AddHours(horaInicio.Hour).AddMinutes(horaInicio.Minute),
                           Duracao = duracaoAula.Minutes + duracaoAula.Hours*60,
                           TipoAula = tipoAula
                       };
        }

        public static Docente GetDocente(string line)
        {
            //ID_UC;DS_Discip;ID_Turno;Data_Aula;Hora_Inicio;Hora_Fim;ID_Sala;Sala;Docente
            string[] items = line.Split(new[] {';', ','});

            //verifica se o nº de argumento é o correcto
            if (items.Length != 9)
                throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (9).");

            string docenteNome = items[8];

            return new Docente
                       {
                           Id = -1,
                           Nome = docenteNome
                       };
        }

        public static Sala GetSala(string line)
        {
            //ID_UC;DS_Discip;ID_Turno;Data_Aula;Hora_Inicio;Hora_Fim;ID_Sala;Sala;Docente
            string[] items = line.Split(new[] {';', ','});

            //verifica se o nº de argumento é o correcto
            if (items.Length != 9)
                throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (9).");

            int salaId = Convert.ToInt32(items[6]);
            string sala = items[7];

            return new Sala
                       {
                           Id = salaId,
                           Designacao = sala
                       };
        }

        public static UnidadeCurricular GetUnidadeCurricular(string line)
        {
            //ID_UC;DS_Discip;ID_Turno;Data_Aula;Hora_Inicio;Hora_Fim;ID_Sala;Sala;Docente
            //ORIGEM;CD_CURSO;CD_ALUNO;CD_DISCIP
            string[] items = line.Split(new[] { ';', ',' });

            //verifica se o nº de argumento é o correcto
            if (items.Length == 9)
            {
                int ucId = Convert.ToInt32(items[0]);
                string disciplina = items[1].Substring(0, items[1].IndexOf("(") - 1);
                return new UnidadeCurricular {Id = ucId, Nome = disciplina};
            }
            if (items.Length == 4)
            {
                int ucId = Convert.ToInt32(items[3]);
                int curso = Convert.ToInt32(items[1]);
                return new UnidadeCurricular { Id = ucId, CursoId = curso };
            }
            
            throw new ArgumentOutOfRangeException("O nº de campos da linha não corresponde ao esperado (9 ou 4).");
        }
    }
}